﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AbstraX.Contracts;
using AbstraX.BuildWizard;
using Mvvm;
using ActiproSoftware.Windows.Controls.Wizard;
using ActiproSoftware.Compatibility;
using Utils;

namespace SolutionFramework.Views
{
    public partial class BuildWizard : UserControl, IWizardContainerWindow
    {
        private IWizardContainer wizardContainer;
        private Divelements.SandDock.Window window;
        private bool finished;
        private IWizardFrame currentFrame;
        public event EventHandler<EventArgs<IWizardFrame>> OnWizardAborted;
        public event EventHandler<EventArgs<IWizardFrame>> OnWizardClosed;

        public BuildWizard(IWizardContainer wizardContainer)
        {
            this.wizardContainer = wizardContainer;
            wizardContainer.ContainerWindow = this;

            InitializeComponent();
        }

        public void AddWizardFrame(IWizardFrame frame)
        {
            WizardPage page = new WizardPage();
            WizardPage dummyPage;

            page.PageType = WizardPageType.Interior;
            page.Caption = frame.Caption;
            page.Description = frame.Description;
            page.Content = frame.FrameControl;

            this.Wizard.SelectionChanging += (sender, e) =>
            {
                if ((e.SelectionFlags & WizardPageSelectionFlags.NextPageCommand) == WizardPageSelectionFlags.NextPageCommand)
                {
                    if (((WizardPage) e.OldValue).Content == frame.FrameControl)
                    {
                        frame.NextPageCommand.Execute(e.SelectionFlags);
                        this.Wizard.IsNextButtonEnabled = frame.NextEnabled;
                        this.Wizard.IsFinishButtonEnabled = frame.FinishEnabled;
                    }

                    this.Wizard.Items.Cast<WizardPage>().ToList()
                        .Where(p => p == e.NewValue && p.Content == frame.FrameControl)
                        .ToList()
                        .ForEach(p =>
                        {
                            currentFrame = frame;

                            frame.ShowFrameCommand.Execute(p);
                            this.Wizard.IsNextButtonEnabled = frame.NextEnabled;
                            this.Wizard.IsFinishButtonEnabled = frame.FinishEnabled;
                        });
                }
                else if ((e.SelectionFlags & WizardPageSelectionFlags.PreviousPageCommand) == WizardPageSelectionFlags.PreviousPageCommand)
                {
                    if (((WizardPage)e.OldValue).Content == frame.FrameControl)
                    {
                        frame.PreviousPageCommand.Execute(e.SelectionFlags);
                    }

                    this.Wizard.Items.Cast<WizardPage>().ToList()
                        .Where(p => p == e.NewValue && p.Content == frame.FrameControl)
                        .ToList()
                        .ForEach(p => 
                            {
                                currentFrame = frame;

                                frame.ShowFrameCommand.Execute(p);
                                this.Wizard.IsNextButtonEnabled = frame.NextEnabled;
                                this.Wizard.IsFinishButtonEnabled = frame.FinishEnabled;
                            });
                }
            };

            window.Closing += (sender, e) =>
            {
                if (!finished)
                {
                    OnWizardAborted(this, new EventArgs<IWizardFrame>(currentFrame));
                    frame.CancelCommand.Execute(e);
                }

                OnWizardClosed(this, new EventArgs<IWizardFrame>(currentFrame));
            };

            this.Wizard.Canceled += (sender, e) =>
            {
                frame.CancelCommand.Execute(e);
                window.Close();
            };

            this.Wizard.Finished += (sender, e) =>
            {
                finished = true;

                frame.FinishCommand.Execute(e);
                window.Close();
            };

            if (this.Wizard.Items.Count == 1)
            {
                currentFrame = frame;
            }

            this.Wizard.Items.Add(page);

            dummyPage = this.Wizard.Items.Cast<WizardPage>().Where(p => (p.Tag != null && p.Tag == "DummyPage")).SingleOrDefault();

            if (dummyPage != null)
            {
                this.Wizard.Items.Remove(dummyPage);
            }
            else
            {
                dummyPage = new WizardPage();

                dummyPage.PageType = WizardPageType.Blank;
                dummyPage.Content = "Please wait!";
                dummyPage.Tag = "DummyPage";
            }

            this.Wizard.Items.Add(dummyPage);
        }

        public object Window
        {
            set 
            {
                window = (Divelements.SandDock.Window)value;
            }
        }

        public void EnableNext()
        {
            this.Wizard.IsNextButtonEnabled = true;
        }
    }
}
